package com.mach.platform.handlers;

import com.google.common.collect.Lists;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Administrator
 * @Description: 单车碳排量计算
 * @Package: com.mach.platform.handlers
 * @time 2018/9/13 0013 22:45
 */
public class AvgCarbonFactory {

	private       Map<String, Object> producton;
	private final String              KEY_LEGEND = "legend";
	private final String              KEY_XDATA  = "xaxis";
	private final String              KEY_YDATA  = "yaxis";
	private final String              KEY_TITLE  = "title";
	private final String              MAP_YEAR   = "fyear";
	private final String              MAP_MONTH  = "fmonth";
	private final String              MAP_DAY    = "fday";

	private String        timeType;
	private String        date;
	private List<Map>     actConsume;
	private List<Map>     planConsume;
	// 实际产量
	private List<Map>     actProductions;
	// 计划产量
	private List<Map>     planProductions;
	private LinkedList    yDatas     = new LinkedList();
	private List<Integer> legendNums = null;

	public AvgCarbonFactory (String timeType, String date, List<Map> actConsume, List<Map> planConsume,
			List<Map> actProductions, List<Map> planProductions) {
		this.timeType = timeType;
		this.date = date;
		this.actConsume = actConsume;
		this.planConsume = planConsume;
		this.actProductions = actProductions;
		this.planProductions = planProductions;
		producton = new HashMap<>();
		producton.put(KEY_YDATA, yDatas);
	}

	public Map<String, Object> work ( ) {

		makeXdata();
		makeYdatas(actConsume, actProductions, true);
		makeYdatas(planConsume, planProductions, false);

		return producton;
	}

	private void makeYdatas (List<Map> useObj, List<Map> productionObj, boolean ifFirst) {

		// 先处理 没有 产量数据的情况
		if (productionObj.size() == 0 || useObj.size() == 0) {
			if (ifFirst) {
				yDatas.addFirst(Collections.EMPTY_LIST);
			} else {
				yDatas.addLast(Collections.EMPTY_LIST);
			}
			return;
		}

		List<Object> objectList = null;

		// 处理 map中要获取的key名称
		String targetMapKeyName = "全年份".equals(timeType) ? MAP_YEAR : ( "年度".equals(timeType) ? MAP_MONTH : MAP_DAY );
		// 如果都不为0的话，两种情况：数据长度一致（先排序）; 数据长度不一致（补0）

		// 先以 legendNums 为长度标准，不都长的，补领
		// 先排序
		List<Map> hadSortUserObj = useObj.stream().sorted(Comparator.comparingInt(
				oo -> Integer.parseInt(oo.get(targetMapKeyName).toString()))).collect(Collectors.toList());

		List<Map> hadSortProdObj = productionObj.stream().sorted(Comparator.comparingInt(
				oo -> Integer.parseInt(oo.get(targetMapKeyName).toString()))).collect(Collectors.toList());

		List<Integer> compareListUse = hadSortUserObj.stream()
		                                             .map(ite -> Integer.parseInt(ite.get(targetMapKeyName).toString()))
		                                             .collect(Collectors.toList());
		List<Integer> compareListProd = hadSortProdObj.stream().map(ite -> Integer.parseInt(
				ite.get(targetMapKeyName).toString())).collect(Collectors.toList());

		// 不管够不够，洗一遍，不同长度则 补0

		for (int i = 0; i < legendNums.size(); i++) {

			Integer cutDate = legendNums.get(i);
			if (!compareListUse.contains(cutDate)) {
				Map newMap = new HashMap();
				newMap.put("num", 0);
				newMap.put(targetMapKeyName, cutDate);
				if (i < compareListUse.size()) {
					hadSortUserObj.add(i, newMap);
				} else {
					hadSortUserObj.add(newMap);
				}
			}

			if (!compareListProd.contains(cutDate)) {
				Map newMap = new HashMap();
				newMap.put("num", 0D);
				newMap.put(targetMapKeyName, cutDate);
				if (i < compareListProd.size()) {
					hadSortProdObj.add(i, newMap);
				} else {
					hadSortProdObj.add(newMap);
				}
			}

		}

		List<Object> childrenData = Lists.newArrayList();

		for (int i = 0; i < legendNums.size(); i++) {

			Map useOne = hadSortUserObj.get(i);
			Map proOne = hadSortProdObj.get(i);

			if (useOne.get("num") == null || Double.parseDouble(useOne.get("num").toString()) == 0D
					    || proOne.get("num") == null || Double.parseDouble(proOne.get("num").toString()) == 0D) {
				childrenData.add(0D);
			} else {
				childrenData.add(new BigDecimal(useOne.get("num").toString())
						                 .divide(new BigDecimal(proOne.get("num").toString()), 1,
								                 RoundingMode.HALF_UP));
			}

		}

		if (ifFirst) {
			yDatas.addFirst(childrenData);
		} else {
			yDatas.addLast(childrenData);
		}

	}

	public void makeXdata ( ) {

		List<String> values = null;

		switch (timeType) {
			case "全年份":

				if (actConsume.size() == 0 && planConsume.size() == 0) {
					values = Collections.emptyList();
					break;
				}
				// 获取长度较长的
				legendNums = Stream.concat(actConsume.stream(), planConsume.stream())
				                   .map(item -> Integer.parseInt(item.get("fyear").toString())).distinct()
				                   .sorted((o1, o2) -> o1 - o2).collect(Collectors.toList());

				values = legendNums.stream().map(item -> item + "年").collect(Collectors.toList());

				producton.put(KEY_TITLE, timeType + "单车碳排走势");
				break;

			case "年度":
				legendNums = Stream.iterate(1, num -> num + 1).limit(12).collect(Collectors.toList());
				values = legendNums.stream().map(item -> item + "月").collect(Collectors.toList());
				producton.put(KEY_TITLE, date.substring(0, 4) + "单车碳排走势");
				break;
			case "月度":
				legendNums = Stream.iterate(1, num -> num + 1)
				                   .limit(DateTime.parse(date).dayOfMonth().getMaximumValue())
				                   .collect(Collectors.toList());
				values = legendNums.stream().map(item -> item + "日").collect(Collectors.toList());
				producton.put(KEY_TITLE, date.substring(5, 7) + "单车碳排走势");
				break;
			case "日度":

				break;
			default:
				break;
		}

		producton.put(KEY_XDATA, values);
		producton.put(KEY_LEGEND, new String[] { "单台实际碳排", "单台计划碳排" });

	}

}
